/*
* Copyright (c) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
var serverPath = '//magabot-control-application.googlecode.com/hg/';

//Account of the application
var jid = "magabot.hangouts@gmail.com";
var password = "hangouts12345";

var robotEmail;
var lastMessage = " ";

var isForwardKeyDown = 0;

// Remember some divs for easy reference later.
var participantsDiv = document.getElementById('participants');
var whosTalkin = document.getElementById('whosTalkin');

// What ID has the highlight right now?
var currentHighlightedParticipantId = null;

// Displays the video feed that would normally be
// visible if the app.  The DefaultVideoFeed generally
// shows feeds based on their volume level.
function showDefaultFeed() {

  // Remove the highlighting.
  if (currentHighlightedParticipantId) {
    gapi.hangout.av.clearAvatar(currentHighlightedParticipantId);
  }

  currentHighlightedParticipantId = null;

  var feed = gapi.hangout.layout.getDefaultVideoFeed();
  var canvas = gapi.hangout.layout.getVideoCanvas();

  canvas.setVideoFeed(feed);
  canvas.setWidth(800);
  canvas.setPosition(300, 0);
  canvas.setVisible(true);

  // Update the text
  updateDisplayedParticipant();
}

function getDisplayNameFromId(id) {
  var participant = gapi.hangout.getParticipantById(id);
  if (!participant || !participant.hasAppEnabled) {
    return 'An unknown person';
  }
  return participant.person.displayName;
}

// Updates div to say who is shown in the video canvas
function updateDisplayedParticipant() {
  if (currentHighlightedParticipantId) {
    whosTalkin.innerHTML = '<p>Locked to ' +
        getDisplayNameFromId(currentHighlightedParticipantId) + '</p>';
    return;
  }

  var id = gapi.hangout.layout.getDefaultVideoFeed().getDisplayedParticipant();
  whosTalkin.innerHTML = '<p>Currently ' +
      getDisplayNameFromId(id) + '</p>';
}

// Shows a list of participants with clickable buttons to lock them
function updateParticipants() {
  var retVal = '<ul>';

  var participants = gapi.hangout.getParticipants();

  for (var index in participants) {
    var part = participants[index];

    retVal += '<li>' + getDisplayNameFromId(part.id) +
        ' <input type="button" value="Lock" id="lockMeButton"' +
            'onClick="lockParticipant(\'' + part.id + '\')"/></li>';
  }

  retVal += '</ul>';

  // Check to see if the current participant
  if (currentHighlightedParticipantId &&
      !gapi.hangout.getParticipantById(currentHighlightedParticipantId)) {
    currentHighlightedParticipantId = null;
    showDefaultFeed();
  }

  participantsDiv.innerHTML = retVal;
}

// Displays the video feed for a given participant
function lockParticipant(partId) {

  // Remove any previous highlighting.
  if (currentHighlightedParticipantId) {
    gapi.hangout.av.clearAvatar(currentHighlightedParticipantId);
  }

  // Remember who is selected
  currentHighlightedParticipantId = partId;
  // Highlight this user with the red rectangle.
  gapi.hangout.av.setAvatar(currentHighlightedParticipantId,
      'http://mediakit001.appspot.com/static/images/participantHighlight.png');

  // Set the feed
  var feed = gapi.hangout.layout.createParticipantVideoFeed(partId);
  var canvas = gapi.hangout.layout.getVideoCanvas();

  canvas.setVideoFeed(feed);
  canvas.setWidth(600);
  canvas.setPosition(300, 50);
  canvas.setVisible(true);

  // Update the text
  updateDisplayedParticipant();
}

//Set the direction on the server and send the message what a button is clicked
function setDirection(direction) {
  console.log(direction + ' button clicked.');
  
  //Set on the server
  gapi.hangout.data.submitDelta({'direction': direction});  
  var robotsCombobox = document.getElementById('robotsCombobox');
  if(robotsCombobox.selectedIndex == 1){
	gapi.hangout.data.submitDelta({'robot1DirectionState': direction});
  }else if(robotsCombobox.selectedIndex == 2){
	gapi.hangout.data.submitDelta({'robot2DirectionState': direction});
  }

  //Send the chat messages
  if(direction == "forward")
	sendChatMessage('w');
  else if(direction == "backward")
	sendChatMessage('s');
  else if(direction == "left")
	sendChatMessage('a');
  else if(direction == "right")
	sendChatMessage('d');
  else if(direction == "stop")
	sendChatMessage('p');

  //Ask to choose a robot before start trying to control them
  if(!robotEmail || robotEmail == "")
    alert("Choose a robot first!");
}

//Add or update a option on the combobox
function updateOptionButtonClick() {
  //Ask the details
  var option = prompt("What's the option you want to change? \n    1 or 2?","1");
  var username = prompt("Enter the username","magabot");

  if (username != null) {
    username += "@gmail.com";
    //Sends the hangout url to the new user
    var hangoutUrl = gapi.hangout.getHangoutUrl();
    $.xmpp.sendMessage({to:username, body: hangoutUrl});
    //Sets the new user on the server
	if(option == "1") {
	  gapi.hangout.data.submitDelta({'robot1Email': username});
	} else if(option == "2") {
	  gapi.hangout.data.submitDelta({'robot2Email': username});
	} else {
	  alert("Please enter a correct option number");
	}
  }
}

//Send the chat message if it's different from the last one
function sendChatMessage(message){
  if(message != lastMessage){
    $.xmpp.sendMessage({to:robotEmail, body: message});
  }
  
  lastMessage = message;
}

//Sets the direction when a key is pressed
function keyPressed(e){
  var unicode=e.keyCode? e.keyCode : e.charCode;

  switch(unicode)
  {
    case 38: //Up arrow
      setDirection('forward');
	  isForwardKeyDown = 1;
      break;
    case 40: //Down arrow
      setDirection('backward');
      break;
    case 37: //Left arrow
      setDirection('left');
      break;
    case 39: //Right arrow
      setDirection('right');
      break;
    case 32: //Spacebar
      setDirection('stop');
      break;
  }
}

//Sets the direction (stop) when a key is released
function keyReleased(e){
  var unicode=e.keyCode? e.keyCode : e.charCode;

  switch(unicode)
  {
    case 38: //Up arrow
      setDirection('stop');
	  isForwardKeyDown = 0;
      break;
    case 40: //Down arrow
      setDirection('stop');
      break;
    case 37: //Left arrow
	  if(isForwardKeyDown)
	    setDirection('forward');
	  else
        setDirection('stop');
      break;
    case 39: //Right arrow
      if(isForwardKeyDown)
	    setDirection('forward');
	  else
        setDirection('stop');
      break;
  }
}

//Updates the UI
function updateStateUi(state) {
  var robotsCombobox = document.getElementById('robotsCombobox');
  //Updates the selected robot email
  robotEmail = robotsCombobox.options[robotsCombobox.selectedIndex].value;
  
  var directionState;
  if(robotsCombobox.selectedIndex == 1){
	directionState = state['robot1DirectionState'];
  }else if(robotsCombobox.selectedIndex == 2){
	directionState = state['robot2DirectionState'];
  }
  
  //Updates the combobox options
  robotsCombobox.options[1].innerHTML = state['robot1Email'];
  robotsCombobox.options[1].value = state['robot1Email'];
  robotsCombobox.options[2].innerHTML = state['robot2Email'];
  robotsCombobox.options[2].value = state['robot2Email'];
  
  //Updates the buttons images
  updateButtons(directionState.toString());
  
  //Calls the functions the a key is press or released
  document.onkeydown = keyPressed;
  document.onkeyup = keyReleased;
  
  updateParticipants();
  updateDisplayedParticipant();    
}

//Updates the buttons images
function updateButtons(direction) {
  //Gets the buttons
  var forwardButton = document.getElementById('forward');
  var backwardButton = document.getElementById('backward');
  var leftButton = document.getElementById('left');
  var rightButton = document.getElementById('right');
  var stopButton = document.getElementById('stop');
  
  //Sets all the buttons with the regular images
  forwardButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/forward.png';
  backwardButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/backward.png';
  leftButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/left.png';
  rightButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/right.png';		
  stopButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/stop.png';		
  
  //Sets the correspondent button with the selected version of the image
  if(direction == "forward")
	forwardButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/forwardSelected.png';
  else if(direction == "backward")
	backwardButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/backwardSelected.png';
  else if(direction == "left")
	leftButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/leftSelected.png';
  else if(direction == "right")
	rightButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/rightSelected.png';
  else if(direction == "stop")
	stopButton.src = 'http://magabot-control.googlecode.com/hg/static/pictures/stopSelected.png';
}

//Updated the selected robot email when the selected item of the combobox changes
function robotsComboboxChanged(){
  var robotsCombobox = document.getElementById('robotsCombobox');
  robotEmail = robotsCombobox.options[robotsCombobox.selectedIndex].value;
}

// A function to be run at app initialization time which registers our callbacks
function init() {
  console.log('Init app.');

  var apiReady = function(eventObj) {
    if (eventObj.isApiReady) {
      console.log('API is ready');
	  //updateParticipants();
      //updateDisplayedParticipant();    

      gapi.hangout.data.onStateChanged.add(function(eventObj) {
        updateStateUi(eventObj.state);
      });
      gapi.hangout.onParticipantsChanged.add(function(eventObj) {
        updateParticipantsUi(eventObj.participants);
        updateParticipants();
      });
	  // Every time the default video feed changes, we want the text to change
	  // Note that these events go off whether or not the default video feed
	  // is currently displayed.
	  gapi.hangout.layout.getDefaultVideoFeed().onDisplayedParticipantChanged.add(function(eventObj) {
		console.log('Displayed participant changed');
		updateDisplayedParticipant();
	  });
      
      updateStateUi(gapi.hangout.data.getState());
      updateParticipantsUi(gapi.hangout.getParticipants());

      gapi.hangout.onApiReady.remove(apiReady);
    }
  };

	//An example of bosh server. This site is working but it can change or go down.
	//If you are going to have a production site, you must install your own BOSH server
	var url ="http://bosh.metajack.im:5280/xmpp-httpbind";
	var contactList = $("#contacts");
	$.xmpp.connect({url:url, jid: jid, password: password,
		onConnect: function(){
			$.xmpp.setPresence(null);
		},
		onPresence: function(presence){
			var contact = $("<li>");
			contact.append("<a href='javascript:void(0)'>"+ presence.from +"</a>");
			contact.find("a").click(function(){
					var id = MD5.hexdigest(presence.from);
					var conversation = $("#"+id);
					if(conversation.length == 0)
						openChat({to:presence.from});
			});
			contactList.append(contact);
		}
    });
	
  // This application is pretty simple, but use this special api ready state
  // event if you would like to any more complex app setup.
  gapi.hangout.onApiReady.add(apiReady);
  showDefaultFeed();
}

gadgets.util.registerOnLoadHandler(init);
